package zap

import (
	"time"

	"github.com/spf13/cast"
	"go.uber.org/zap"
)

func valueToZap(k, v any) zap.Field {
	key := cast.ToString(k)
	switch v := v.(type) {
	case string:
		return zap.String(key, v)
	case int:
		return zap.Int(key, v)
	case int32:
		return zap.Int32(key, v)
	case int64:
		return zap.Int64(key, v)
	case uint:
		return zap.Uint(key, v)
	case uint32:
		return zap.Uint32(key, v)
	case uint64:
		return zap.Uint64(key, v)
	case float32:
		return zap.Float32(key, v)
	case float64:
		return zap.Float64(key, v)
	case bool:
		return zap.Bool(key, v)
	case []byte:
		return zap.Binary(key, v)
	case error:
		return zap.Error(v)
	case time.Duration:
		return zap.Duration(key, v)
	case time.Time:
		return zap.Time(key, v)
	default:
		return zap.Any(key, v)
	}
}

func kvsToZapFields(kvs ...any) []zap.Field {
	if len(kvs) == 0 {
		return []zap.Field{}
	}
	if len(kvs) == 1 {
		return []zap.Field{zap.String("msg", cast.ToString(kvs[0]))}
	}

	first := kvs[0]
	switch first.(type) {
	case zap.Field:
		fields := make([]zap.Field, 0, len(kvs))
		for _, kv := range kvs {
			fields = append(fields, kv.(zap.Field))
		}
		return fields

	default:
		if len(kvs)%2 != 0 {
			kvs = append(kvs, "missing")
		}
		fields := make([]zap.Field, 0, len(kvs)/2)
		for i := 0; i < len(kvs); i += 2 {
			fields = append(fields, valueToZap(kvs[i], kvs[i+1]))
		}
		return fields

	}

}
